/*
  provider 的使用
  1.创建Model，混入ChangeNotifier，当数据改变时发送通知
  2.使用ChangeNotifierProvider，套在app外层
  3.改变数据用context.read、获取数据用context.watch
 */

import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => Counter()),
      // 可以添加多个ChangeNotifierProvider
    ],
    child: const MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print('home page build');
    return Scaffold(
      appBar: AppBar(
        title: const Text('Provider'),
      ),
      body: Center(
        child: Column(
          children: [
            // 获取数据用watch，但是会让整个页面刷新
            // Text('数量：${context.watch<Counter>().count}'),

            // 使用builder函数，传入当前上下文，达到局部刷新的目的
            Builder(builder: (ctx) {
              print('count build');
              return Text('数量：${ctx.watch<Counter>().count}');
            }),

            // 使用consumer，也可以局部刷新
            // Consumer(builder: (BuildContext context, Counter value, Widget child){
            //   return Text('数量：${value.count}');
            // }),

            // selector
            // 只监听有需要的数据
            // 第一个泛型表示数据，第二个表示字段类型
            // selector返回具体字段，builder使用字段类型
            // 也是局部刷新
            Selector<Counter, String>(
                builder: (BuildContext context, String name, Widget? child) {
              return Text('名字：$name');
            }, selector: (ctx, count) {
              return count._name;
            }),
            ElevatedButton(
                onPressed: () {
                  // 改变状态用read
                  context.read<Counter>().add();
                  String randName = new WordPair.random().toString();
                  context.read<Counter>().changeName(randName);
                },
                child: Text('增加'))
          ],
        ),
      ),
    );
  }
}

class Counter with ChangeNotifier {
  int _count = 0; // 默认值也是null
  String _name = 'James';

  void add() {
    _count++;
    notifyListeners();
  }

  void changeName(String name) {
    _name = name;
    notifyListeners();
  }

  get count => _count;

  get name => _name;
}
